package eu.template;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import eu.AppContext;
import eu.common.config.ConfigEngine;
import eu.common.toolkits.ResourceUtil;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 页面上下文，在使用之前必须调用init()方法执行初始化。
 * 线程内共享。
 * @author WZZ
 * 
 */
public abstract class TemplateContext {

	/**
	 * FreeMaker 数据模板
	 */
	private static ThreadLocal<Map<String, Object>> param = new ThreadLocal<Map<String, Object>>();
	
	/**
	 * 
	 */
	private static ThreadLocal<Map<String, Object>> privateContext = new ThreadLocal<Map<String, Object>>();

	/**
	 * 
	 */
	private static Configuration tplCfg = null;

	/**
	 * 
	 * @author WZZ
	 * 
	 */
	private interface Keys {

		String TEMPLATE = "template";

	}

	private interface Config {

		String TEMPLATE_PATH = "template_path";

		String TEMPLATE_ENCODING = "template_encoding";

		String TEMPLATE_CONFIG = "template_config";
	}
	
	public static void initContext() {
		if (tplCfg != null) {
			return;
		}
		// 初始化模板引擎
		try {
			tplCfg = new Configuration();
			tplCfg.setDirectoryForTemplateLoading(new File(AppContext.getConfig(Config.TEMPLATE_PATH)));
			tplCfg.setObjectWrapper(new DefaultObjectWrapper());
			if (AppContext.containsConfig(Config.TEMPLATE_ENCODING))
				tplCfg.setDefaultEncoding(AppContext
						.getConfig(Config.TEMPLATE_ENCODING));
			tplCfg.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
			tplCfg.setDateFormat("yyyy-MM-dd");
			tplCfg.setNumberFormat("##0");
			ConfigEngine engine = ConfigEngine.getEngine(ConfigEngine.EngineType.XMLEngine, 
					ResourceUtil.getResourcePath(AppContext.getConfig(Config.TEMPLATE_CONFIG)),"UTF-8");
			// 解析配置文件
			for (String name : engine.getSubNames("/template/extension-function")) {
				try {
					tplCfg.setSharedVariable(name, 
							Class.forName(engine.getValue("/template/extension-function/" + name)).newInstance());
				} catch (Exception e) {
					e.printStackTrace();
					continue;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 初始化页面上下文
	 */
	public static void init() {
		TemplateContext.privateContext.set(new HashMap<String, Object>());
		TemplateContext.param.set(new HashMap<String, Object>());
	}

	public static void setTemplate(String template) {
		TemplateContext.privateContext.get().put(Keys.TEMPLATE, template);
	}

	public static String getTemplate() {
		return (String) TemplateContext.privateContext.get().get(Keys.TEMPLATE);
	}

	/**
	 * 放置参数
	 * 
	 * @param name
	 * @param param
	 */
	public static void putParam(String name, Object param) {
		TemplateContext.param.get().put(name, param);
	}

	/**
	 * 放置参数
	 * 
	 * @param params
	 */
	public static void putParams(Map<String,? extends Object> params) {
		TemplateContext.param.get().putAll(params);
	}


	/**
	 * 输出页面
	 * 
	 * @param out
	 * @throws IOException 
	 * @throws TemplateException 
	 */
	public static void flush(Writer out) throws IOException, TemplateException {
		Template tpl = getTemplate(getTemplate());
		tpl.process(param.get(), out);
	}

	/**
	 * 获取模板
	 * 
	 * @param path
	 * @return
	 * @throws IOException
	 */
	private static Template getTemplate(String path) throws IOException {
		return tplCfg.getTemplate(path);
	}

}
